import 'dart:io';

import 'package:ble_demo/config/app_config.dart';
import 'package:device_info/device_info.dart';
import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:shared_preferences/shared_preferences.dart';

final GlobalKey<NavigatorState> navigatorKey =
    new GlobalKey<NavigatorState>(); // 全局跳转key

class HttpUtil {
  static HttpUtil instance;
  Dio dio;
  BaseOptions options;
  String baseUrl = AppConfig.BASEURL;

  CancelToken cancelToken = new CancelToken();

  static HttpUtil getInstance() {
    if (null == instance) instance = new HttpUtil();
    return instance;
  }

  /*
   * config it and create
   */
  HttpUtil() {
    //BaseOptions、Options、RequestOptions 都可以配置参数，优先级别依次递增，且可以根据优先级别覆盖参数
    options = new BaseOptions(
      //请求基地址,可以包含子路径
      baseUrl: baseUrl,
      //连接服务器超时时间，单位是毫秒.
      connectTimeout: 20000,
      //响应流上前后两次接受到数据的间隔，单位为毫秒。
      receiveTimeout: 1000,
      //Http请求头.
      headers: {
        //do something
        "version": "1.0.0"
      },
    );

    dio = new Dio(options);

    //抓包代理
//      (dio.httpClientAdapter as DefaultHttpClientAdapter).onHttpClientCreate = (client) {
//        client.findProxy = (uri) {
//          return 'PROXY 10.0.2.182:8888';
//        };
//      };

    //添加拦截器
    dio.interceptors.add(InterceptorsWrapper(onRequest: (RequestOptions options) async {
      SharedPreferences prefs = await SharedPreferences.getInstance();
      // cookie
      String cookie = prefs.getString('loginCookie');
      if (cookie != null) {
        options.headers['Cookie'] = cookie;
      }else{
        /// 测试用，上线改成跳转登录页面
        options.headers['Cookie'] =  "services_component_session=BxK1tHobs4sDWExtSxrYGyyPMSkhb7IAJ2on8leh";

        EasyLoading.showError("cookie失效，重新登录");
        /// 清除缓存并跳转登录页
        Future.delayed(Duration(seconds: 3), () {
          // navigatorKey.currentState.popAndPushNamed('/signin'); // 跳转
        });
      }
      // device info
      if (prefs.getString('ua') != null) {
        options.headers['ua'] = prefs.getString('ua');
      } else {
        DeviceInfoPlugin deviceInfoPlugin = DeviceInfoPlugin();
        if (Platform.isAndroid) {
          var info = await deviceInfoPlugin.androidInfo;
          prefs.setString('ua', info.model);
          options.headers['ua'] = info.model;
        } else {
          var info = await deviceInfoPlugin.iosInfo;
          prefs.setString('ua', info.utsname.machine);
          options.headers['ua'] = info.utsname.machine;
        }
      }
      print("发送http请求...........");
      return options;
    }, onResponse: (Response response) {
      if (response.data["code"] == 510) {
        /// cookie失效跳转登录，待补充
        // Application.router.navigateTo(navigatorKey.currentState.context, '/signin',clearStack: true,transition: TransitionType.fadeIn);
        EasyLoading.showError(response.data['message'].toString());
        /// 清除缓存并跳转登录页
        Future.delayed(Duration(seconds: 3), () {
          // navigatorKey.currentState.popAndPushNamed('/signin'); // 跳转
        });
      }
      print("接收http响应...........");
      return response;
    }, onError: (DioError e) {
      print("http请求异常............");
      print(e.toString());
      return e;
    }));
  }

  /*
   * get请求
   */
  get(url, {data, options, cancelToken}) async {
    Response response;
    try {
      response = await dio.get(url,
          queryParameters: data, options: options, cancelToken: cancelToken);
    } on DioError catch (e) {
      print('get error---------$e');
      formatError(e);
    }
    return response.data;
  }

  /*
   * post请求
   */
  post(url, {data, options, cancelToken}) async {
    FormData formData = FormData.fromMap(data);
    Response response;
    try {
      response = await dio.post(url,
          data: formData, options: options, cancelToken: cancelToken);
    } on DioError catch (e) {
      print(e.response);
    }
    return response.data;
  }

  /*
   * 下载文件
   */
  downloadFile(urlPath, savePath) async {
    Response response;
    try {
      response = await dio.download(urlPath, savePath,
          onReceiveProgress: (int count, int total) {
        //进度
        print("$count $total");
      });
    } on DioError catch (e) {
      formatError(e);
    }
    return response.data;
  }

  /*
   * error统一处理
   */
  void formatError(DioError e) {
    if (e.type == DioErrorType.CONNECT_TIMEOUT) {
      // It occurs when url is opened timeout.
      print("连接超时");
    } else if (e.type == DioErrorType.SEND_TIMEOUT) {
      // It occurs when url is sent timeout.
      print("请求超时");
    } else if (e.type == DioErrorType.RECEIVE_TIMEOUT) {
      //It occurs when receiving timeout
      print("响应超时");
    } else if (e.type == DioErrorType.RESPONSE) {
      // When the server response, but with a incorrect status, such as 404, 503...
      print("出现异常");
    } else if (e.type == DioErrorType.CANCEL) {
      // When the request is cancelled, dio will throw a error with this type.
      print("请求取消");
    } else {
      //DEFAULT Default error type, Some other Error. In this case, you can read the DioError.error if it is not null.
      print("未知错误");
    }
  }

  /**
   * 取消请求
   * 同一个cancel token 可以用于多个请求，当一个cancel token取消时，所有使用该cancel token的请求都会被取消。
   * 所以参数可选
   */
  void cancelRequests(CancelToken token) {
    token.cancel("cancelled");
  }

  delete(url, {data, options, cancelToken}) async {
    Response response;
    try {
      response = await dio.delete(url,
          queryParameters: data, options: options, cancelToken: cancelToken);
      print('delete success---------${response.data}');
    } on DioError catch (e) {
      print('delete error---------$e');
      formatError(e);
    }
    return response.data;
  }
}
